<template>
    <!-- 个人中心页面容器 -->
    <div class="personal">
      <!-- 个人信息区域 -->
      <div class="personal-info">
        <!-- 用户头像 -->
        <!-- 点击可打开头像修改对话框 -->
        <el-image class="personal-img" fit="contain" :src="attachImageUrl(userPic)" @click="dialogTableVisible = true" />
        <!-- 用户基本信息 -->
        <div class="personal-msg">
          <div class="username">{{ personalInfo.username }}</div>
          <div class="introduction">{{ personalInfo.introduction }}</div>
        </div>
        <!-- 修改个人信息按钮 -->
        <el-button class="edit-info" round :icon="Edit" @click="goPage()">修改个人信息</el-button>
      </div>
      <!-- 个人收藏歌曲列表区域 -->
      <div class="personal-body">
        <!-- 歌曲列表组件 -->
        <!-- 传入收藏歌曲数据，并监听数据变化事件 -->
        <song-list :songList="collectSongList" :show="true" @changeData="changeData"></song-list>
      </div>
      <!-- 修改头像对话框 -->
      <el-dialog v-model="dialogTableVisible" title="修改头像">
        <!-- 头像上传组件 -->
        <upload></upload>
      </el-dialog>
    </div>
  </template>
  
  <script setup lang="ts">
  /**
   * Personal.vue - 个人中心页面组件 
   */
  import { nextTick, ref, computed, watch, reactive } from "vue";
  import { useStore } from "vuex";
  import { Edit } from "@element-plus/icons-vue";// 导入Element Plus图标
  import SongList from "@/components/SongList.vue"; // 歌曲列表组件，用于展示收藏的歌曲
  import Upload from "../setting/Upload.vue"; // 头像上传组件
  import mixin from "@/mixins/mixin"; // 包含路由管理等通用功能
  import { HttpManager } from "@/api"; // 封装API请求的管理工具
  import { RouterName } from "@/enums"; // 路由名称常量
  
  // 类型定义
  interface UserInfo {
    username: string; // 用户名
    userSex: string; // 性别
    birth: string; // 生日
    location: string; // 所在地
    introduction: string; // 个人介绍
  }
  
  interface ResponseBody {
    success: boolean; // 操作是否成功
    data?: any; // 响应数据
  }
  
  // 创建Vuex store实例
  const store = useStore();
  
  // 解构混合器中的路由管理函数
  const { routerManager } = mixin();
  
  /**
   * 图片URL处理函数
   * 将相对路径的图片URL转换为完整的URL
   * @param url - 原始图片URL（相对路径）
   * @returns 完整的图片URL（绝对路径）
   */
  const attachImageUrl = (url: string) => {
    return HttpManager.attachImageUrl(url);
  };
  
  // 响应式数据：头像修改对话框显示状态
  const dialogTableVisible = ref(false); // 默认为隐藏
  
  // 响应式数据：用户收藏的歌曲列表
  const collectSongList = ref([]); // 收藏的歌曲列表，初始为空数组
  
  /**
   * 响应式数据：用户个人信息对象
   * 包含用户名、性别、生日、所在地和个人介绍
   */
  const personalInfo = reactive<UserInfo>({
    username: "", // 用户名
    userSex: "", // 性别
    birth: "", // 生日
    location: "", // 所在地
    introduction: "", // 个人介绍
  });
  
  // 计算属性：用户ID
  // 从Vuex store中获取当前登录用户的ID
  const userId = computed(() => store.getters.userId);
  
  // 计算属性：用户头像
  // 从Vuex store中获取当前登录用户的头像URL
  const userPic = computed(() => store.getters.userPic);
  
  /**
   * 监听用户头像变化
   * 当用户头像更新后，自动关闭头像修改对话框
   */
  watch(userPic, () => {
    dialogTableVisible.value = false;
  });
  
  /**
   * 跳转到设置页面
   * 通过路由管理函数跳转到用户设置页面，用于修改个人信息
   */
  function goPage() {
    routerManager(RouterName.Setting, { path: RouterName.Setting });
  }
  
  /**
   * 获取用户个人信息
   * 从后端API获取指定用户的详细信息并更新到组件状态中
   * @param id - 用户ID，用于查询特定用户的信息
   */
  async function getUserInfo(id: string | number) {
    // 调用API获取用户详情
    const result = (await HttpManager.getUserOfId(id)) as ResponseBody;
  
    // 更新用户信息到响应式对象
    if (result.data && result.data.length > 0) {
      personalInfo.username = result.data[0].username;
      personalInfo.userSex = result.data[0].sex;
      personalInfo.birth = result.data[0].birth;
      personalInfo.introduction = result.data[0].introduction;
      personalInfo.location = result.data[0].location;
    }
  }
  
  /**
   * 获取用户收藏的歌曲列表
   * 先获取收藏的歌曲ID，再逐个获取歌曲详情
   * @param userId - 用户ID，用于查询特定用户收藏的歌曲
   */
  async function getCollection(userId: string | number) {
    // 清空当前收藏列表，避免数据重复
    collectSongList.value = []
  
    // 调用API获取用户收藏的歌曲ID列表
    const result = (await HttpManager.getCollectionOfUser(userId)) as ResponseBody;
    collectSongList.value = result.data || []; // 存放收藏的歌曲ID，默认为空数组 

  }
  /**
   * 数据更新函数
   * 当子组件数据变化时（如删除收藏歌曲），重新获取收藏列表
   * 作为子组件事件的回调函数
   */
  function changeData() {
    getCollection(userId.value); // 重新获取当前用户的收藏歌曲列表
  }
  /**
   * 组件挂载后初始化数据
   * 在DOM更新完成后，获取用户信息和收藏歌曲列表
   * 确保组件初次渲染时能显示最新的用户数据
   */
  nextTick(() => {
    getUserInfo(userId.value); // 获取当前用户的个人信息
    getCollection(userId.value); // 获取当前用户收藏的歌曲列表
  });
  </script>
  
  <style lang="scss" scoped>
  // 导入Sass变量
  @use "@/assets/css/var.scss" as *;
  
  /**
   * 个人中心页面容器样式
   * 设置顶部内边距和背景
   */
  .personal {
    padding-top: $header-height + 150px; // 顶部内边距，为头部导航和个人信息留出空间
  
    // 背景装饰元素
    &::before {
      content: "";
      background-color: $color-blue-shallow; // 浅蓝色背景
      position: absolute;
      top: 0;
      width: 100%;
      height: $header-height + 150px;
    }
  }
  
  /**
   * 个人信息区域样式
   */
  .personal-info {
    position: relative; // 相对定位，为内部绝对定位元素提供参考
    margin-bottom: 60px;
  
    // 用户头像样式
    .personal-img {
      height: 200px;
      width: 200px;
      border-radius: 50%; // 圆形头像
      border: 5px solid $color-white; // 白色边框
      position: absolute;
      top: -180px;
      left: 50px;
      cursor: pointer; // 鼠标悬停显示指针
    }
  
    // 用户信息文本样式
    .personal-msg {
      margin-left: 300px; // 与头像保持适当距离
      position: absolute;
      top: -120px;
  
      // 用户名样式
      .username {
        font-size: 50px;
        font-weight: 600;
      }
  
      // 个人简介样式
      .introduction {
        font-size: 20px;
        font-weight: 500;
      }
    }
  
    // 修改信息按钮样式
    .edit-info {
      position: absolute;
      right: 10vw;
      margin-top: -120px;
    }
  }
  
  /**
   * 响应式媒体查询 - 中大屏幕
   * 当屏幕宽度大于等于sm断点时应用
   */
  @media screen and (min-width: $sm) { // sm通常为768px
    .personal-body {
      padding: 0px 100px; // 设置左右内边距
    }
  }
  
  /**
   * 响应式媒体查询 - 小屏幕
   * 当屏幕宽度小于sm断点时应用
   */
  @media screen and (max-width: $sm) { // sm通常为768px
    .edit-info {
      display: none; // 在小屏幕上隐藏编辑按钮
    }
  }
  </style>